import { Server } from 'http';
import { GameConfig } from '../entity/game_config';
import { RedisHelper } from '../redis/redis';
import { SocketServer } from '../socket/server';
import { Timestamp } from 'typeorm';
import { isUndefined, isNull } from 'util';

type loggerFunctionType = (message: string) => void;

/**
 * 活动助手
 */
export class ActivityHelper {

    /// 用于缓存的 key
    programOneProgressCacheKey: string = 'hr_cache_program_one';
    programTwoProgressCacheKey: string = 'hr_cache_program_two';
    programThreeProgressCacheKey: string = 'hr_cache_program_three';

    programOneCurProgress: number = 0;
    programTwoCurProgress: number = 0;
    programThreeCurProgress: number = 0;

    /// 用于通知页面的信号
    signalUpdateOne: string = 'update_one_program';
    signalOneOver: string = 'update_one_over_program';
    signalUpdateTwo: string = 'update_two_program';
    signalTwoOver: string = 'update_two_over_program';
    signalUpdateThree: string = 'update_three_program';
    signalThreeOver: string = 'update_three_over_program';
    signalUpdateTotal: string = 'update_total_program';
    signalBegin: string = 'update_begin_program';
    signalOver: string = 'update_over_program';

    programOneProgress: number;
    programTwoProgress: number;
    programThreeProgress: number;
    programStep: number;
    programBeginTime: any;
    programOneOverTime: number;
    programTwoOverTime: number;
    programThreeOverTime: number;

    temp1: any = '0';
    temp2: any = '0';
    temp3: any = '0';

    private static instance: ActivityHelper;

    public init = async () => {
        const conf = new GameConfig();
        const confInfo = await conf.getConfig();
        this.programOneProgress = confInfo.program_one_progress;
        this.programTwoProgress = confInfo.program_two_progress;
        this.programThreeProgress = confInfo.program_three_progress;
        this.programStep = confInfo.program_step;

        RedisHelper.instance.setCacheValue(this.programOneProgressCacheKey, '0');
        RedisHelper.instance.setCacheValue(this.programTwoProgressCacheKey, '0');
        RedisHelper.instance.setCacheValue(this.programThreeProgressCacheKey, '0');

        const moment = require('moment');
        this.programBeginTime = new moment();
        this.programOneOverTime = 0;
        this.programTwoOverTime = 0;
        this.programThreeOverTime = 0;

        SocketServer.instance.emitMessageToAll(this.signalBegin, '1');
    }

    public initTemp = async () => {
        // const conf = new GameConfig();
        const confInfo = {
            'program_one_progress': 100,
            'program_two_progress': 100,
            'program_three_progress': 100,
            'program_step': 10
        };
        this.programOneProgress = confInfo.program_one_progress;
        this.programTwoProgress = confInfo.program_two_progress;
        this.programThreeProgress = confInfo.program_three_progress;
        this.programStep = confInfo.program_step;

        this.temp1 = '0';
        this.temp2 = '0';
        this.temp3 = '0';
    }

    static getInstance() {
        if (ActivityHelper.instance === undefined) {
            ActivityHelper.instance = new ActivityHelper();
        }

        return ActivityHelper.instance;
    }

    public GetProgress = async () => {
        const curOneProgress = await RedisHelper.instance.getCacheValue(this.programOneProgressCacheKey);
        const curTwoProgress = await RedisHelper.instance.getCacheValue(this.programTwoProgressCacheKey);
        const curThreeProgress = await RedisHelper.instance.getCacheValue(this.programThreeProgressCacheKey);

        return {
            'one': curOneProgress,
            'two': curTwoProgress,
            'three': curThreeProgress,
            'P1': this.programOneProgress,
            'P2': this.programTwoProgress,
            'P3': this.programThreeProgress,
            'step': this.programStep
        };
    }

    public GetProgressT = async () => {
        const curOneProgress = this.temp1;
        const curTwoProgress = this.temp2;
        const curThreeProgress = this.temp3;

        return {
            'one': curOneProgress,
            'two': curTwoProgress,
            'three': curThreeProgress,
            'P1': this.programOneProgress,
            'P2': this.programTwoProgress,
            'P3': this.programThreeProgress,
            'step': this.programStep
        };
    }

    //#region production
    public ProgramOneRun = async () => {
        let curProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programOneProgressCacheKey));
        const curTwoProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programTwoProgressCacheKey));
        const curThreeProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programThreeProgressCacheKey));

        if (curProgress >= this.programOneProgress) {
            const moment = require('moment');
            // 计算项目一用时
            const curTime: any = new moment();
            if (this.programOneOverTime === 0) {
                this.programOneOverTime = moment.duration(curTime.diff(this.programBeginTime)).as('seconds');
            }

            // 通知所有页面 项目一完成
            SocketServer.instance.emitMessageToAll(this.signalUpdateOne, '-1');
            SocketServer.instance.emitMessageToAll(this.signalOneOver, this.programOneOverTime.toString());
        } else {
            curProgress += this.programStep;

            const overProgress: number
                = ((this.programOneProgress - curProgress) < 0) ?
                    0 : (this.programOneProgress - curProgress);

            RedisHelper.instance.setCacheValue(this.programOneProgressCacheKey, curProgress.toString());
            // 通知所有页面 当前项目一的完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateOne, overProgress.toString());

            let curTotalProgress: number
                = (curProgress + curTwoProgress + curThreeProgress) /
                (this.programOneProgress + this.programTwoProgress + this.programThreeProgress);

            curTotalProgress = curTotalProgress > 1 ? 100 : curTotalProgress * 100;

            /// 通知所有页面 当前总体完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTotal, curTotalProgress.toString());
        }
    }

    public ProgramTwoRun = async () => {
        const curOneProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programOneProgressCacheKey));
        let curProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programTwoProgressCacheKey));
        const curThreeProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programThreeProgressCacheKey));

        if (curProgress >= this.programTwoProgress) {
            const moment = require('moment');
            // 计算项目三用时
            const curTime: any = new moment();
            if (this.programTwoOverTime === 0) {
                this.programTwoOverTime = moment.duration(curTime.diff(this.programBeginTime)).as('seconds');
                this.programTwoOverTime = this.programTwoOverTime - this.programOneOverTime;
            }

            // 通知所有页面 项目二完成
            SocketServer.instance.emitMessageToAll(this.signalUpdateTwo, '-1');
            SocketServer.instance.emitMessageToAll(this.signalTwoOver, this.programTwoOverTime.toString());
        } else {
            curProgress += this.programStep;

            const overProgress: number
                = ((this.programOneProgress - curProgress) < 0) ?
                    0 : (this.programOneProgress - curProgress);

            RedisHelper.instance.setCacheValue(this.programTwoProgressCacheKey, curProgress.toString());
            // 通知所有页面 当前项目二的完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTwo, overProgress.toString());

            let curTotalProgress: number
                = (curOneProgress + curProgress + curThreeProgress) /
                (this.programOneProgress + this.programTwoProgress + this.programThreeProgress);

            curTotalProgress = curTotalProgress > 1 ? 100 : curTotalProgress * 100;

            /// 通知所有页面 当前总体完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTotal, curTotalProgress.toString());
        }
    }

    public ProgramThreeRun = async () => {
        const curOneProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programOneProgressCacheKey));
        const curTwoProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programTwoProgressCacheKey));
        let curProgress =
            Number.parseInt(await RedisHelper.instance.getCacheValue(this.programThreeProgressCacheKey));

        if (curProgress >= this.programTwoProgress) {
            const moment = require('moment');
            // 计算项目三用时
            const curTime: any = new moment();
            if (this.programThreeOverTime === 0) {
                this.programThreeOverTime = moment.duration(curTime.diff(this.programBeginTime)).as('seconds');
                this.programThreeOverTime
                    = this.programThreeOverTime - this.programTwoOverTime - this.programOneOverTime;
            }

            // 通知所有页面 项目三完成
            SocketServer.instance.emitMessageToAll(this.signalUpdateThree, '-1');
            SocketServer.instance.emitMessageToAll(this.signalThreeOver, this.programThreeOverTime.toString());
        } else {
            curProgress += this.programStep;

            const overProgress: number
                = ((this.programOneProgress - curProgress) < 0) ?
                    0 : (this.programOneProgress - curProgress);

            RedisHelper.instance.setCacheValue(this.programThreeProgressCacheKey, curProgress.toString());
            // 通知所有页面 当前项目三的完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateThree, overProgress.toString());

            let curTotalProgress: number
                = (curOneProgress + curTwoProgress + curProgress) /
                (this.programOneProgress + this.programTwoProgress + this.programThreeProgress);

            curTotalProgress = curTotalProgress > 1 ? 100 : curTotalProgress * 100;

            /// 通知所有页面 当前总体完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTotal, curTotalProgress.toString());
        }
    }

    public GameOver = () => {
        const totalTime = this.programOneOverTime + this.programTwoOverTime + this.programThreeOverTime;
        SocketServer.instance.emitMessageToAll(this.signalOver, totalTime.toString());
    }
    //#endregion

    // #region 测试代码
    public ProgramOneRunT = async () => {
        let curProgress: number = Number.parseInt(this.temp1);
        const curTwoProgress: number = Number.parseInt(this.temp2);
        const curThreeProgress: number = Number.parseInt(this.temp3);

        if (curProgress >= this.programOneProgress) {
            // 通知所有页面 项目一完成
            SocketServer.instance.emitMessageToAll(this.signalUpdateOne, '-1');
        } else {
            curProgress += this.programStep;
            // RedisHelper.instance.setCacheValue(this.programOneProgressCacheKey, curProgress);
            this.temp1 = curProgress;

            // 通知所有页面 当前项目一的完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateOne, curProgress.toString());

            let curTotalProgress: number
                = (curProgress + curTwoProgress + curThreeProgress) /
                (this.programOneProgress + this.programTwoProgress + this.programThreeProgress);

            curTotalProgress = curTotalProgress > 1 ? 100 : curTotalProgress * 100;

            /// 通知所有页面 当前总体完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTotal, curTotalProgress.toString());
        }
    }

    public ProgramTwoRunT = async () => {
        const curOneProgress: number = Number.parseInt(this.temp1);
        let curProgress: number = Number.parseInt(this.temp2);
        const curThreeProgress: number = Number.parseInt(this.temp3);

        if (curProgress >= this.programTwoProgress) {
            // 通知所有页面 项目二完成
            SocketServer.instance.emitMessageToAll(this.signalUpdateTwo, '-1');
        } else {
            curProgress += this.programStep;
            // RedisHelper.instance.setCacheValue(this.programTwoProgressCacheKey, curProgress);
            this.temp2 = curProgress;

            // 通知所有页面 当前项目二的完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTwo, curProgress.toString());

            let curTotalProgress: number
                = (curOneProgress + curProgress + curThreeProgress) /
                (this.programOneProgress + this.programTwoProgress + this.programThreeProgress);

            curTotalProgress = curTotalProgress > 1 ? 100 : curTotalProgress * 100;

            /// 通知所有页面 当前总体完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTotal, curTotalProgress.toString());
        }
    }

    public ProgramThreeRunT = async () => {
        const curOneProgress: number = Number.parseInt(this.temp1);
        const curTwoProgress: number = Number.parseInt(this.temp2);
        let curProgress: number = Number.parseInt(this.temp3);

        if (curProgress >= this.programTwoProgress) {
            // 通知所有页面 项目三完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateThree, '-1');
        } else {
            curProgress += this.programStep;
            // RedisHelper.instance.setCacheValue(this.programThreeProgressCacheKey, curProgress);
            this.temp3 = curProgress;

            // 通知所有页面 当前项目三的完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateThree, curProgress.toString());

            let curTotalProgress: number
                = (curOneProgress + curTwoProgress + curProgress) /
                (this.programOneProgress + this.programTwoProgress + this.programThreeProgress);

            curTotalProgress = curTotalProgress > 1 ? 100 : curTotalProgress * 100;

            /// 通知所有页面 当前总体完成情况
            SocketServer.instance.emitMessageToAll(this.signalUpdateTotal, curTotalProgress.toString());
        }
    }
    //#endregion
}
